/**
 ******************************************************************************
 * @file    C8624.c
 * @author  Wu Zhe Wei
 * @version V1.0
 * @date
 * @brief   Command and communication driver level with C8624.
 *          Functional configuration and low level display function.
 ******************************************************************************
 /**
  ******************************************************************************
  * @file    C8625.c
  * @author  Wu Zhe Wei
  * @version V1.0
  * @date
  * @brief   Command and communication driver level with C8625. 
  *          Functional configuration and low level display function.
  
         SEG1 A            SEG2 B             SEG3  C           SEG4 D              SEG5  E            SEG6  F            SEG7   G           SEG8  H            SEG9  J            SEG10 K            SEG11   L         SEG12 M             SEG13 N             SEG14 P              SEG15 Q         
GRID1 CF_DisplayBuf[0]   CF_DisplayBuf[1]   CF_DisplayBuf[2]   CF_DisplayBuf[3]   CF_DisplayBuf[4]   CF_DisplayBuf[5]   CF_DisplayBuf[6]   CF_DisplayBuf[7]   CF_DisplayBuf[8]   CF_DisplayBuf[9]   CF_DisplayBuf[10]  CF_DisplayBuf[11]  CF_DisplayBuf[12]  CF_DisplayBuf[13]  CF_DisplayBuf[14] 
GRID2 CF_DisplayBuf[15]  CF_DisplayBuf[16]  CF_DisplayBuf[17]  CF_DisplayBuf[18]  CF_DisplayBuf[19]  CF_DisplayBuf[20]  CF_DisplayBuf[21]  CF_DisplayBuf[22]  CF_DisplayBuf[23]  CF_DisplayBuf[24]  CF_DisplayBuf[25]  CF_DisplayBuf[26]  CF_DisplayBuf[27]  CF_DisplayBuf[28]  CF_DisplayBuf[29]  
GRID3 CF_DisplayBuf[30]  CF_DisplayBuf[31]  CF_DisplayBuf[32]  CF_DisplayBuf[33]  CF_DisplayBuf[34]  CF_DisplayBuf[35]  CF_DisplayBuf[36]  CF_DisplayBuf[37]  CF_DisplayBuf[38]  CF_DisplayBuf[39]  CF_DisplayBuf[40]  CF_DisplayBuf[41]  CF_DisplayBuf[42]  CF_DisplayBuf[43]  CF_DisplayBuf[44] 
GRID4 CF_DisplayBuf[45]  CF_DisplayBuf[46]  CF_DisplayBuf[47]  CF_DisplayBuf[48]  CF_DisplayBuf[49]  CF_DisplayBuf[50]  CF_DisplayBuf[51]  CF_DisplayBuf[52]  CF_DisplayBuf[53]  CF_DisplayBuf[54]  CF_DisplayBuf[55]  CF_DisplayBuf[56]  CF_DisplayBuf[57]  CF_DisplayBuf[58]  CF_DisplayBuf[59] 
GRID5 CF_DisplayBuf[60]  CF_DisplayBuf[61]  CF_DisplayBuf[62]  CF_DisplayBuf[63]  CF_DisplayBuf[64]  CF_DisplayBuf[65]  CF_DisplayBuf[66]  CF_DisplayBuf[67]  CF_DisplayBuf[68]  CF_DisplayBuf[69]  CF_DisplayBuf[70]  CF_DisplayBuf[71]  CF_DisplayBuf[72]  CF_DisplayBuf[73]  CF_DisplayBuf[74]   
GRID6 CF_DisplayBuf[75]  CF_DisplayBuf[76]  CF_DisplayBuf[77]  CF_DisplayBuf[78]  CF_DisplayBuf[79]  CF_DisplayBuf[80]  CF_DisplayBuf[81]  CF_DisplayBuf[82]  CF_DisplayBuf[83]  CF_DisplayBuf[84]  CF_DisplayBuf[85]  CF_DisplayBuf[86]  CF_DisplayBuf[87]  CF_DisplayBuf[88]  CF_DisplayBuf[89] 
GRID7 CF_DisplayBuf[90]  CF_DisplayBuf[91]  CF_DisplayBuf[92]  CF_DisplayBuf[93]  CF_DisplayBuf[94]  CF_DisplayBuf[95]  CF_DisplayBuf[96]  CF_DisplayBuf[97]  CF_DisplayBuf[98]  CF_DisplayBuf[99]  CF_DisplayBuf[100] CF_DisplayBuf[101] CF_DisplayBuf[102] CF_DisplayBuf[103] CF_DisplayBuf[104] 
GRID8 CF_DisplayBuf[105] CF_DisplayBuf[106] CF_DisplayBuf[107] CF_DisplayBuf[108] CF_DisplayBuf[109] CF_DisplayBuf[110] CF_DisplayBuf[111] CF_DisplayBuf[112] CF_DisplayBuf[113] CF_DisplayBuf[114] CF_DisplayBuf[115] CF_DisplayBuf[116] CF_DisplayBuf[117] CF_DisplayBuf[118] CF_DisplayBuf[119]  

  *********************************************************************************************************************************************************************************************************************************************/

#include "./Common_Include.h"

/*
 * @brief  public variable define
 * @note
 */
Ram ty_cmd_config_t tCmdConfig;
Ram ty_cmd_setting_t tCmdSetting;
Ram unsigned char CF_DisplayBuf[CF_BUF_SIZE];

CONST unsigned char BreathGamma[64] = {0, 1, 2, 3, 4, 5, 6, 7,
                                       8, 10, 12, 14, 16, 18, 20, 22,
                                       24, 26, 29, 32, 35, 38, 41, 44,
                                       47, 50, 53, 57, 61, 65, 69, 73,
                                       77, 81, 85, 89, 94, 99, 104, 109,
                                       114, 119, 124, 129, 134, 140, 146, 152,
                                       158, 164, 170, 176, 182, 188, 195, 202,
                                       209, 216, 223, 230, 237, 244, 251, 255};

/**
 * @function CF_SetCurrentCommand()
 * -------------------------------
 * @brief    Configure the current setting command.
 * @param    None
 * @note     None
 */
static void CF_SetCurrentCommand()
{
  tCmdSetting.Current =  tCmdConfig.emCurrentGain;   //  C8625 寄存器1  bit6  bit7 默认0
}

/**
 * @function CF_SetModeCommand()
 * ----------------------------
 * @brief    Configure the mode setting command.
 * @param    None
 * @note     None
 */
static void CF_SetModeCommand()
{
  tCmdSetting.Mode = (tCmdConfig.emClockMode << 7) + (tCmdConfig.emComScan << 2) + (tCmdConfig.emWorkMode << 1) + tCmdConfig.emDataUpdata;
}

/**
 * @function CF_SetDisplayCommand()
 * -------------------------------
 * @brief    Configure the display setting command.
 * @param    None
 * @note     None
 */
static void CF_SetDisplayCommand()
{
  tCmdSetting.Display = (tCmdConfig.emOverT125Protect << 7) + (tCmdConfig.emPwmClock << 4) + (tCmdConfig.emDisplay << 3) + (tCmdConfig.emGhostReduction << 2) + tCmdConfig.emRowBreakTime;
}

/**
 * @function CF_SetControlCommand()
 * -------------------------------
 * @brief    Configure the control setting command.
 * @param    None
 * @note     None
 */
static void CF_SetControlCommand()
{
  tCmdSetting.Control = (tCmdConfig.emSleepFunction << 6) + (tCmdConfig.emAutoSleepFunction << 5) + (tCmdConfig.emGlobalReset << 4) + (tCmdConfig.emSoftReset << 3) + (tCmdConfig.emOverT150Protect << 1) + tCmdConfig.emPowerDownReset;
}

// /**
//  * @function  Drv_I2c_Send_NAck(e_INDEX_C8624)
//  * ----------------------
//  * @brief    Sending one byte to led driver.
//  * @param    sdata - the sending data
//  * @note     None
//  */
// static void CF_SendByte(unsigned char sdata)
// {
//   unsigned char i;

//   for (i = 0; i < 8; i++)
//   {
//     CF_SCL_Write(0);
//     if (sdata & 0x80)
//       CF_SDA_Write(1);
//     else
//       CF_SDA_Write(0);
//     CF_TimeDlyUs();
//     CF_SCL_Write(1);
//     CF_TimeDlyUs();
//     sdata <<= 1;
//   }
//   CF_SCL_Write(0);
// }

/**
 * @function CF_SendCLK()
 * ----------------------
 * @brief    Sending one CLK.
 * @param    None
 * @note     None
 */
// static void Drv_I2c_Send_Byte_Fast(e_INDEX_C8624,)
// {
//   CF_SCL_Write(0);
//   CF_TimeDlyUs();
//   CF_SCL_Write(1);
//   CF_TimeDlyUs();
//   CF_SCL_Write(0);
// }

/**
 * @function CF_SendCommandPackage()
 * --------------------------------
 * @brief    Sending command package to led driver.
 * @param    cmdType - command type
 * @note     None
 */
static void CF_SendCommandPackage(em_cmd_type_t cmdType)
{
  unsigned char checkSum = 0;
  unsigned char command;

  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, 0x5A);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, 0xFF);
  tCmdConfig.emCmdType = cmdType;
  command = (tCmdConfig.emcmdBroadcastEnable << 6) + (tCmdConfig.emCsAddress << 4) + tCmdConfig.emCmdType;
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, command);
  checkSum = 0x5A + 0xFF + command;
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, checkSum);
}

/**
 * @function CF_SendSetPackage()
 * ----------------------------
 * @brief    Sending set package to led driver.
 * @param    None
 * @note     None
 */
static void CF_SendSetPackage()
{
  unsigned char checkSum = 0;

  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, tCmdSetting.Current);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, tCmdSetting.Mode);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, tCmdSetting.Display);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, tCmdSetting.Control);
  checkSum = tCmdSetting.Current + tCmdSetting.Mode + tCmdSetting.Display + tCmdSetting.Control;
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, checkSum);
}

/**
 * @function CF_SendDataFrame()
 * ---------------------------
 * @brief    Sending data frame to led driver.
 * @param    *pDataBuf - point to data buffer
 * @note     None
 */
static void CF_SendDataFrame(unsigned char *pDataBuf)
{
  unsigned char checkSum = 0;
  unsigned short i, dataLength = 0;

  dataLength = CF_SEG_NUM * (tCmdConfig.emComScan + 1);

  CF_SendCommandPackage(CmdCommand);
  CF_SendSetPackage();
  CF_SendCommandPackage(CmdData);

  checkSum = 0;
  for (i = 0; i < dataLength; i++)
  {
    Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, *(pDataBuf + i));
    checkSum += *(pDataBuf + i);
  }
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, checkSum);
}

/**
 * @function CF_ConfigCommand()
 * ---------------------------
 * @brief    Config the command paramaters.
 * @param    None
 * @note     None
 */
void CF_ConfigCommand()
{
  tCmdConfig.emcmdBroadcastEnable = CSMode;          // CSmode
  tCmdConfig.emCsAddress = CsAddress0;               // chip address
  tCmdConfig.emCmdType = CmdCommand;                 // command type
  tCmdConfig.emCurrentGain = mA_30;                  // current value
  tCmdConfig.emClockMode = InternalClock;            // internal clock mode
  tCmdConfig.emComScan = Com8;                       // number of com ports in use
  tCmdConfig.emWorkMode = NormalMode;                // work mode
  tCmdConfig.emDataUpdata = AutomaticUpdate;         // data update mode, recommend automatic update
  tCmdConfig.emOverT125Protect = Otp125Enable;       // temperature protection1 -125?
  tCmdConfig.emPwmClock = Clock1M;                   // pwm clock frequency
  tCmdConfig.emDisplay = DisplayEnable;              // diaplay enable
  tCmdConfig.emGhostReduction = Strong;              // ghosting
  tCmdConfig.emRowBreakTime = PwmCycle8;             // scanning interval
  tCmdConfig.emSleepFunction = SleepDisable;         // sleep enable
  tCmdConfig.emAutoSleepFunction = AutoSleepDisable; // auto sleep disable
  tCmdConfig.emGlobalReset = GlobalDisable;          // global reset (clear RAM)
  tCmdConfig.emSoftReset = SoftDisable;              // soft reset (refresh display)
  tCmdConfig.emOverT150Protect = Otp150Enable;       // temperature protection1 -150?
  tCmdConfig.emPowerDownReset = PowerEnable;         // power-off reset
}

/**
 * @function CF_ReconfigCommand()
 * -----------------------------
 * @brief    Reconfig the command paramaters.
 * @param    None
 * @note     None
 */
void CF_ReconfigCommand()
{
  tCmdConfig.emcmdBroadcastEnable = CSMode;
  tCmdConfig.emCsAddress = CsAddress0;
  tCmdConfig.emCmdType = CmdCommand;
  tCmdConfig.emCurrentGain = mA_30;
  tCmdConfig.emClockMode = InternalClock;
  tCmdConfig.emComScan = Com8;
  tCmdConfig.emWorkMode = NormalMode;
  tCmdConfig.emDataUpdata = AutomaticUpdate;
  tCmdConfig.emOverT125Protect = Otp125Enable;
  tCmdConfig.emPwmClock = Clock8M;
  tCmdConfig.emDisplay = DisplayEnable;
  tCmdConfig.emGhostReduction = Strong;
  tCmdConfig.emRowBreakTime = PwmCycle8;
  tCmdConfig.emSleepFunction = SleepDisable;
  tCmdConfig.emAutoSleepFunction = AutoSleepDisable;
  tCmdConfig.emGlobalReset = GlobalDisable;
  tCmdConfig.emSoftReset = SoftDisable;
  tCmdConfig.emOverT150Protect = Otp150Enable;
  tCmdConfig.emPowerDownReset = PowerEnable;

  CF_SetCurrentCommand();
  CF_SetModeCommand();
  CF_SetDisplayCommand();
  CF_SetControlCommand();
}

/**
 * @function Dev_CF_Init()
 * ------------------
 * @brief    Initlize all led drivers.
 * @param    None
 * @note     None
 */
void Dev_CF_Init(void)
{
  // CF_SDA_Write(1);
  // CF_SCL_Write(1);

  CF_ConfigCommand();
  CF_SetCurrentCommand();
  CF_SetModeCommand();
  CF_SetDisplayCommand();
  CF_SetControlCommand();
}

/**
 * @function Dev_CF_DisplayClearBuf()
 * -----------------------------
 * @brief    Clear all display buffer.
 * @param    None
 * @note     None
 */
void Dev_CF_DisplayClearBuf(void)
{
  unsigned short i;
  unsigned short dataLength = 0;

  dataLength = CF_SEG_NUM * (tCmdConfig.emComScan + 1);

  for (i = 0; i < dataLength; i++)
    CF_DisplayBuf[i] = 0;
}

/**
 * @function Dev_CF_DisplayAll()
 * ------------------------
 * @brief    Display all led with special luminance.
 * @param    lumi - brightness value (0x00 ~ 0xFF)
 * @note     None
 */
void Dev_CF_DisplayAll(unsigned char lumi)
{
  unsigned short i;
  unsigned short dataLength = 0;

  dataLength = CF_SEG_NUM * (tCmdConfig.emComScan + 1);

  for (i = 0; i < dataLength; i++)
    CF_DisplayBuf[i] = lumi;

  CF_SendDataFrame(CF_DisplayBuf);
  CF_SendCommandPackage(CmdDataUpdate);
  Drv_I2c_Send_NAck(e_INDEX_C8624);
}

/**
 * @function Dev_CF_SendAddressData()
 * ---------------------------
 * @brief    Sending Addressdata to led driver.
 * @param    DataAddr  - Data Address
 *           Data        Display Data
 * @note     None
 */
void Dev_CF_SendAddressData(unsigned char DataAddr, unsigned char Data)
{
  unsigned char checkSum = 0;
  CF_SendCommandPackage(CmdCommand);
  CF_SendSetPackage();
  CF_SendCommandPackage(CmdAdressData);
  checkSum = 0;
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, DataAddr);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, Data);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, 0xff);
  checkSum = (DataAddr + Data + 0xff);
  Drv_I2c_Send_Byte_Fast(e_INDEX_C8624, checkSum);
  CF_SendCommandPackage(CmdDataUpdate);
  Drv_I2c_Send_NAck(e_INDEX_C8624);
}

/**
 * @function Dev_CF_DisplayBufAutomatic()
 * ---------------------------------
 * @brief    Write luminance of the display buffer to led
 *           driver, automatic update the display.
 * @param    None
 * @note     None
 */
void Dev_CF_DisplayBufAutomatic(void)
{
  CF_SendDataFrame(CF_DisplayBuf);
  CF_SendCommandPackage(CmdDataUpdate);
  Drv_I2c_Send_NAck(e_INDEX_C8624);
}

/**
 * @function Dev_CF_DisplayIntoSleep()
 * ------------------------------
 * @brief    Led driver into sleep mode.
 * @param    None
 * @note     None
 */
void Dev_CF_DisplayIntoSleep(void)
{
  CF_SendCommandPackage(CmdCommand);
  tCmdConfig.emSleepFunction = SleepEnable;
  CF_SetControlCommand();
  CF_SendSetPackage();
  CF_SendCommandPackage(CmdSleep);
  Drv_I2c_Send_NAck(e_INDEX_C8624);
}

/**
 * @function Dev_CF_DisplayWakeUp()
 * ---------------------------
 * @brief    Led driver wakeup from sleep mode.
 * @param    None
 * @note     None
 */
void Dev_CF_DisplayWakeUp(void)
{
  CF_SendCommandPackage(CmdWakeUp);
  CF_SendCommandPackage(CmdCommand);
  tCmdConfig.emSleepFunction = SleepDisable;
  CF_SetControlCommand();
  CF_SendSetPackage();
  Drv_I2c_Send_NAck(e_INDEX_C8624);
}

/**
 * @function Dev_CF_DisplayBreathBuf()
 * ------------------------------
 * @brief    Show breathing effect in display buffer.
 * @param    BREATH_TIME - time to run a single step
 * @retval   sbreathBuf  - breathing display buf
 */
unsigned char Dev_CF_DisplayBreathBuf(void)
{
  static unsigned char sbreathCount = 0;
  static unsigned char sbreathBuf = 0;
  static unsigned char sbreathFlag = 0;

  if (!sbreathFlag)
  {
    if ((sbreathCount + 1) < sizeof(BreathGamma))
      sbreathCount++;
    else
      sbreathFlag = 1;
  }
  else
  {
    if (sbreathCount > 0)
      sbreathCount--;
    else
      sbreathFlag = 0;
  }
  sbreathBuf = BreathGamma[sbreathCount];

  return (sbreathBuf);
}

/**
 * @function Dev_CF_DisplayMarqueeBuf()
 * -------------------------------
 * @brief    Show marquee effect in display buffer.
 * @param    MARQUEE_TIME - time to run a single step
 * @retval   smarqueeBuf  - address of marquee display buf
 */
unsigned char *Dev_CF_DisplayMarqueeBuf(void)
{
  unsigned char i, tmp;
  static Ram unsigned char smarqueeBuf[MARQUEE_NUM] = {8, 16, 32, 64, 128, 255};

  // if (MARQUEE_TIME)
  {
    for (i = (MARQUEE_NUM - 1); i > 0; i--)
    {
      if (i == (MARQUEE_NUM - 1))
        tmp = smarqueeBuf[i];
      smarqueeBuf[i] = smarqueeBuf[i - 1];

      if (i == 1)
        smarqueeBuf[i - 1] = tmp;
    }
  }

  return (smarqueeBuf);
}
void Dev_C8624_Scan(void)
{
  static unsigned char tick = 0;
  if (Drv_Autoload_Ntick_u8(&tick, 40ul)) // 40ms处理一次   DXY
  {
    //  Dev_CF_DisplayClearBuf();
    //  Dev_CF_DisplayAll(0xFF);         //全亮
     Dev_CF_DisplayBufAutomatic();
  }
}

/* [] END OF FILE */
